﻿using LaunchAllaround.DesignPattern;
using LaunchAllaround.DesignPattern.MVC;
using LaunchAllaround.Sound;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LaunchAllaround.Key
{
    [Serializable]
    public class KeyModel : Model<KeyModel>, Resettable<KeyModel>
    {
        /// <summary>
        /// Create the KeyModel with a default non-valid Path.
        /// Adds the KeyUI to its Views.
        /// </summary>
        public KeyModel()
        {
            string path = "(Select a sound from your library)";
            this.song = new Song(path);
            this.stream = new WaveStream(song);
            this.modelFunc = new ModelImpl<KeyModel>();
            this.AddView(new KeyUI(this));
        }

        /// <summary>
        /// Create the KeyModel with a default non-valid Path.
        /// Adds the KeyUI passed in argument to its Views.
        /// </summary>
        /// <param name="kui">KeyUI is the view of the Key</param>
        public KeyModel(KeyUI kui)
        {
            string path = "(Select a sound from your library)"; ;
            this.song = new Song(path);
            this.stream = new WaveStream(song);
            this.modelFunc = new ModelImpl<KeyModel>();
            kui.SetModel(this);
            this.AddView(kui);
        }

        /// <summary>
        /// Create the KeyModel with a Path.
        /// </summary>
        /// <param name="path">This is the path which locate the sound associated to the Key</param>
        public KeyModel(string path)
        {
            this.Path = path;
        }


        [NonSerialized] private WaveStream stream;
        public WaveStream Stream { get { return this.stream; } set { this.stream = value; } }

        private Song song;
        public Song Song 
        { 
            get { return this.song; }
            set 
            { 
                this.song = value;
                this.stream = new WaveStream(this.song);
            } 
        }
        public string Path
        {
            get { return this.song.SongPath; }
            set 
            {
                if (value != this.Path)
                {
                    this.song.SongPath = value;
                    this.Stream = new WaveStream(this.song);
                    this.RefreshViews(new RefreshPath(this));
                    this.RefreshViews(new RefreshPreview(this));
                }
            }
        }
        public float Volume
        {
            get { return this.song.Volume; }
            set 
            { 
                this.song.Volume = value;
                this.stream = new WaveStream(this.song);
                this.RefreshViews(new RefreshVolume(this));
            }
        }

        // # Model Functionalities ######
        private ModelImpl<KeyModel> modelFunc;

        public void AddView(View<KeyModel> v)
        {
            this.modelFunc.AddView(v);
        }
        public Container<View<KeyModel>> GetViews()
        {
            return this.modelFunc.GetViews();
        }

        public void ClearViews()
        {
            this.modelFunc.ClearViews();
        }

        public void RefreshViews(RefreshEvent<KeyModel> ev)
        {
            this.modelFunc.RefreshViews(ev);
        }
        // ##############################

        public void Reset(KeyModel pattern)
        {
            this.Path = pattern.Path;
            this.Volume = pattern.Volume;
        }
    }
}
